﻿using System;
using System.Collections.Generic;
using System.IO;
using CSJ2K.Util.IO;

namespace CSJ2K.Jpc.Segments
{
    /// <summary>Region of interest (RGN)</summary>
    /// <comment>
    /// <b>Function:</b> Signals the presence of an ROI in the codestream.<br/>
    /// Usage: Main and first tile-part header of a given tile. If used in the main header, it 
    ///      refers to the ROI scaling value for one component in the whole image, valid for all
    ///      tiles except those with an RGN marker segment. When used in the tile-part header, 
    ///      the scaling value is valid only for one component in that tile. There may be at most 
    ///      one RGN marker segment for each component in either the main or tile-part headers. 
    ///      The RGN marker segment for a particular component which appears in a tile-part 
    ///      header overrides any marker for that component in the main header, for the tile in 
    ///      which it appears. If there are multiple tile-parts in a tile, then this marker 
    ///      segment shall be found only in the first tile-part header. <br/>
    /// <b>Length:</b> Variable.
    /// </comment>
    public class RGN : Segment
    {
        /// <summary>The index of the component to which this marker segment relates.</summary>
        public ushort C;

        /// <summary>Region of Interest Styles</summary>
        public enum ROIStyles : byte
        {
            /// <summary>Implicit ROI (maximum shift)</summary>
            Implicit = 0 
        }
        /// <summary>ROI style for the current Region of Interest.</summary>
        public ROIStyles S; 

        /// <summary>Parameter for Region of Interest style designated in RGN.S</summary>
        public Nullable<byte> SP;

        public RGN(Stream source)
            : this(source, (Markers)StreamUtil.ReadBUInt16(source)) { }
        public RGN(Stream source, Markers marker)
            : base(source, marker, true)
        {
            if (marker != Markers.RGN) throw (new ApplicationException("Attempting to create segment of the wrong type."));

            C = StreamUtil.ReadBUInt16(source);
            S = (ROIStyles)StreamUtil.ReadOctet(source);
            if (S == ROIStyles.Implicit) SP = StreamUtil.ReadOctet(source);
        }
    }
}
